﻿
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text;

namespace ConsoleApplication1
{
    public enum Status { readyToTransform, waitSourceImg }
    public class ImgHelper
    {
        /* //对象分割的部分核心代码：
         public Bitmap objSegmentation()
{
   if (stu > Status.readyToTransform)
       return sourceImg;
   else if (stu == Status.waitSourceImg)
       return null;

   if (sourceImg == null)
       return null;

   bool Over = false;
   while (Over == false)
   {
       //取得一个种子像素
       node pxs = null;
       foreach (var item in blackPixs)
       {
           if (item.accessed == false)
           {
               pxs = item;
               break;
           }
       }

       //根据种子像素找出被污染的区域 并把对应的位置设置为已访问
       //设置第一个节点
       startPoint = new Point(pxs.x, pxs.y);
       zouguo = new Dictionary<int, List<node>>();
       int qibu = 0;
       List<node> stepOne = new List<node>();
       stepOne.Add(new node() { parent = startPoint, current = startPoint });
       zouguo.Add(qibu, stepOne);
       qibu++;

       //进行广度搜索 直到搜索完一片区域为止
       bool isgogogo = false;
       do
       {
           isgogogo = besideOf(qibu - 1);
           qibu++;
           //if (qibu > 10)
           //    break;
       } while (isgogogo);

       //遍历当前被腐蚀的那一片区域 
       //并把所有节点添加到一个线性数组里去

       int top = height - 1;
       int bottom = 0;
       int left = cols - 1;
       int right = 0;

       RegionOfObj bedestory = new RegionOfObj();
       bedestory.pixs = new List<Point>();
       foreach (var item in zouguo.Values)
       {
           foreach (var item2 in item)
           {
               bedestory.pixs.Add(item2.current);
               //找出黑色像素里已经被腐蚀过的 把标示设置为已访问
               for (int i = 0; i < blackPixs.Count; i++)
               {
                   if (item2.current.X == blackPixs[i].x && item2.current.Y == blackPixs[i].y)
                   {
                       blackPixs[i].accessed = true;
                       if (blackPixs[i].x > right)
                           right = blackPixs[i].x;
                       if (blackPixs[i].x < left)
                           left = blackPixs[i].x;
                       if (blackPixs[i].y < top)
                           top = blackPixs[i].y;
                       if (blackPixs[i].y > bottom)
                           bottom = blackPixs[i].y;
                   }
               }
           }
       }

       Rectangle rec = new Rectangle(left, top, right - left + 1, bottom - top + 1);


       bedestory.rect = rec;
       //往最终呈现数据里加入结果
       groupedObj.Add(bedestory);

       //直到黑色像素所有的区域都被访问 就退出
       Over = true;
       foreach (var item in blackPixs)
       {
           if (item.accessed == false)
           {
               Over = false;
               break;
           }
       }
       //break;
   }


   stu = Status.readyToRecognition;
   return sourceImg;
}
         */

        /*//模板匹配部分核心代码：
         public string recognition()
{
    if (stu == Status.waitSourceImg)
        return "";
    else if (stu > Status.readyToRecognition)
        return recognition_result;
    else if (stu == Status.readyToTransform)
        objSegmentation();

    
    //如果没有模板文件 则生成他
    if (File.Exists("0.png") == false || File.Exists("1.png") == false || File.Exists("2.png") == false ||
        File.Exists("3.png") == false || File.Exists("4.png") == false || File.Exists("5.png") == false ||
        File.Exists("6.png") == false || File.Exists("7.png") == false || File.Exists("8.png") == false ||
        File.Exists("9.png") == false)
        createTempleFile();


    //载入模板
    Image[] templateImg = new Image[10]{
        Image.FromFile("0.png"),Image.FromFile("1.png"),Image.FromFile("2.png"),Image.FromFile("3.png"),Image.FromFile("4.png"),
    Image.FromFile("5.png"),Image.FromFile("6.png"),Image.FromFile("7.png"),Image.FromFile("8.png"),Image.FromFile("9.png")};

    GraphicsUnit uu = GraphicsUnit.Pixel;
    string result = "";
    for (int i = 0; i < groupedObj.Count; i++)//遍历所有对象
    {
        float mach = 0.000f;
        string chr_tmp = " ";
        for (int j = 0; j < templateImg.Length; j++)//0-9每个字符进行比对
        {
            //处理等比例缩放 算了也不用等比例了。
            Bitmap scaleImg = new Bitmap(groupedObj[i].rect.Width, groupedObj[i].rect.Height);
            Graphics gph = Graphics.FromImage(scaleImg);
            gph.Clear(Color.White);
            gph.DrawImage(templateImg[j], scaleImg.GetBounds(ref uu), templateImg[j].GetBounds(ref uu), GraphicsUnit.Pixel);

            float mach_tmp = 0;
            for (int k = 0; k < scaleImg.Height; k++)
            {
                for (int l = 0; l < scaleImg.Width; l++)
                {
                    Color tmp_cor = scaleImg.GetPixel(l, k);
                    Color trg_cor = sourceImg.GetPixel(groupedObj[i].rect.Location.X + l, groupedObj[i].rect.Location.Y + k);
                    if (tmp_cor.R == trg_cor.R && tmp_cor.G == trg_cor.G && tmp_cor.B == trg_cor.B)//如果像素匹配上
                        mach_tmp += 1;
                }
            }
            if ((mach_tmp / (float)(groupedObj[i].rect.Width * groupedObj[i].rect.Height)) > mach)
            {
                mach = (mach_tmp / (float)(groupedObj[i].rect.Width * groupedObj[i].rect.Height));
                chr_tmp = j.ToString();
            }
        }
        if (mach < 0.6f)
            result += "?";
        else
            result += chr_tmp;
    }
    recognition_result = result;
    stu = Status.complete;
    return result;
}
         */

        /// <summary>
        /// 图像灰度化
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        public static Bitmap ToGray(Bitmap bmp)
        {
            for (int i = 0; i < bmp.Width; i++)
            {
                for (int j = 0; j < bmp.Height; j++)
                {
                    //获取该点的像素的RGB的颜色
                    Color color = bmp.GetPixel(i, j);
                    //利用公式计算灰度值
                    int gray = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
                    Color newColor = Color.FromArgb(gray, gray, gray);
                    bmp.SetPixel(i, j, newColor);
                }
            }
            return bmp;
        }

        /// <summary>
        /// 图像灰度反转
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        public static Bitmap GrayReverse(Bitmap bmp)
        {
            for (int i = 0; i < bmp.Width; i++)
            {
                for (int j = 0; j < bmp.Height; j++)
                {
                    //获取该点的像素的RGB的颜色
                    Color color = bmp.GetPixel(i, j);
                    Color newColor = Color.FromArgb(255 - color.R, 255 - color.G, 255 - color.B);
                    bmp.SetPixel(i, j, newColor);
                }
            }
            return bmp;
        }

        /// <summary>
        /// 图像二值化1：取图片的平均灰度作为阈值，低于该值的全都为0，高于该值的全都为255
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        public static Bitmap ConvertTo1Bpp1(Bitmap bmp)
        {
            int average = 0;
            for (int i = 0; i < bmp.Width; i++)
            {
                for (int j = 0; j < bmp.Height; j++)
                {
                    Color color = bmp.GetPixel(i, j);
                    average += color.B;
                }
            }
            average = (int)average / (bmp.Width * bmp.Height);

            for (int i = 0; i < bmp.Width; i++)
            {
                for (int j = 0; j < bmp.Height; j++)
                {
                    //获取该点的像素的RGB的颜色
                    Color color = bmp.GetPixel(i, j);
                    int value = 255 - color.B;
                    Color newColor = value > average ? Color.FromArgb(0, 0, 0) : Color.FromArgb(255, 255, 255);
                    bmp.SetPixel(i, j, newColor);
                }
            }
            return bmp;
        }

        /// <summary>
        /// 图像二值化2
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        public static Bitmap ConvertTo1Bpp2(Bitmap img)
        {
            int w = img.Width;
            int h = img.Height;
            Bitmap bmp = new Bitmap(w, h, PixelFormat.Format1bppIndexed);
            BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
            for (int y = 0; y < h; y++)
            {
                byte[] scan = new byte[(w + 7) / 8];
                for (int x = 0; x < w; x++)
                {
                    Color c = img.GetPixel(x, y);
                    if (c.GetBrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
                }
                Marshal.Copy(scan, 0, (IntPtr)((int)data.Scan0 + data.Stride * y), scan.Length);
            }
            return bmp;
        }
    }
}
